// $Id: baseworldobject.h 470 2008-05-27 16:27:22Z agjermun $
// Baseclass for all objects in the physical space
//
// ml278
// Copyright (C) 2008 Bjørn Øivind Bjørnsen, Aleksander Gjermundsen, Knut Andre Tidemann, Thomas Hansen
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

#ifndef __BASEWORLDOBJECT_H
#define __BASEWORLDOBJECT_H

#include "Ogre.h"
#include <btBulletCollisionCommon.h>
#include <btBulletDynamicsCommon.h>

using namespace Ogre;

/**
 * Baseclass for objects in the graphical and physical worlds.
 * Holds scenenode, entity, collision shape and rigid body and provides a couple of true virtuals to allow for easy
 * updating, initialising and destruction of physics.
*/
class BaseWorldObject
{
protected:
	SceneNode 		*mNode;         /**< Object's SceneNode - holds position and orientation in space, etc */
	SceneManager 		*mMgr;          /**< Ogre's SceneManager */
	Entity 			*mEnt;          /**< entitiy which holds the object */

	String 			mObjectName;    /**< unique object name */
	String			mMesh;          /**< filename of the mesh-file for the object */

	Vector3 		mPosition;      /**< position vector for the object */ 
	Vector3			mHalfSize;      /**< half-size of the object */

	btDynamicsWorld		*mWorld;        /**< physics world object (Bullet) */
	btCollisionShape	*mColShape;     /**< collision shape object (Bullet) */
	btRigidBody 		*mBody;         /**< rigid body object (Bullet) */

public:
	BaseWorldObject(SceneManager *pMgr,SceneNode *pNode, btDynamicsWorld *world, const String &mesh, const String &objectName, const Vector3 &position);
	BaseWorldObject(SceneManager *pMgr,SceneNode *pNode, btDynamicsWorld *world, const String &objectName);
	virtual ~BaseWorldObject();

	// virtuals
	virtual void update(Real elapsedTime = 0);

	virtual void initPhysics() = 0;
	virtual void exitPhysics() = 0;
	
	virtual void setPos(Vector3 &pos)
	{
		mNode->setPosition(pos);
		mPosition = pos;
	}

	virtual void setMesh(String &meshName)
	{
		// TODO Load new mesh here, and apply to this object
		mMesh = meshName;
	}

	// gets
	const SceneNode *getSceneNode() const
	{
		return(mNode);
	}

	const SceneManager *getSceneManager() const
	{
		return(mMgr);
	}

	const Entity *getEntity() const
	{
		return(mEnt);
	}

	const String getObjectName() const
	{
		return(mObjectName);
	}

	const String getMesh() const
	{
		return(mMesh);
	}

	const Vector3 getPos() const
	{
		return(mPosition);
	}

	const Vector3 getHalfSize() const
	{
		return(mHalfSize);
	}
	
	const Vector3 getSize() const
	{
		return(Vector3(mHalfSize.x*2, mHalfSize.y*2, mHalfSize.z*2));
	}

        const Quaternion getOrientation() const
        {
                return mNode->getOrientation();
        }

	const btDynamicsWorld *getDynamicsWorld() const
	{
		return(mWorld);
	} 
	
	const btCollisionShape *getColShape() const
	{
		return(mColShape);
	}

	const btRigidBody *getRigidBody() const
	{
		return(mBody);
	}

	// sets
	void setName(String &objectName)
	{
		mObjectName = objectName;
	}
};

#endif //#ifndef __BASEWORLDOBJECT_H
